package cz.cvut.fit.web.nakupniSeznam.ws;

import javax.ws.rs.DELETE;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cz.cvut.fit.web.nakupniSeznam.KeyGenerator;
import cz.cvut.fit.web.nakupniSeznam.constants.DBConstants;
import cz.cvut.fit.web.nakupniSeznam.constants.WSConstants;
import cz.cvut.fit.web.nakupniSeznam.dao.UserDAO;
import cz.cvut.fit.web.nakupniSeznam.data.User;
import cz.cvut.fit.web.nakupniSeznam.ws.conv.ErrorConverter;
import cz.cvut.fit.web.nakupniSeznam.ws.conv.InfoConverter;
import cz.cvut.fit.web.nakupniSeznam.ws.conv.UserConverter;

@Path("/user")
public class Users {
	
	private static final Logger LOG = LoggerFactory.getLogger(Users.class);
	public static final String LOG_OK = "ws succesfully called on user";
	public static final String DELETE_COMPLETE = "user succesfully deleted";
	
	@Context
	private UriInfo context;
	private String key;

	
	//====================== PUT ======================//
	@PUT
	@Produces(WSConstants.WS_PRODUCES)
	/**
	 * Create new list
	 * @return
	 */
	public Response putUser(@Context HttpHeaders hh) {
		Response.ResponseBuilder builder = Response
				.status(Response.Status.CREATED);

		KeyGenerator generator = new KeyGenerator();

		// try to find key in header
		key = AuthLibrary.getKey(hh, builder, LOG);
		if (key == null) {
			//TODO set right status code
			return builder.build();
		}

		// check key format
		if (AuthLibrary.checkKeyLength(key, builder, LOG) == false) {
			//TODO set right status code
			return builder.build();
		}

		try {
			User oldUser = UserDAO.getInstance().getByKey(key);

			if (oldUser == null) {
				builder.status(Response.Status.NOT_FOUND);
				builder.entity(new ErrorConverter(WSConstants.RESULT_NOT_FOUND));
				return builder.build();

			} else {
				String generatedKey = generator.generateKey();
				UserDAO.getInstance().changeKey(key, generatedKey);
				oldUser.setKey(generatedKey);

				UserConverter userConverter = new UserConverter(oldUser);

				builder.header(WSConstants.HEADER_LOCATION,
						context.getAbsolutePath());
				builder.entity(userConverter);
			}

		} catch (NullPointerException ex) {
			builder.status(Response.Status.BAD_REQUEST);
			builder.entity(new ErrorConverter(DBConstants.DB_BAD_DATA_FORMAT));
			LOG.error(WSConstants.RESULT_FAILED, ex);
			return builder.build();
		}

		LOG.debug(Users.LOG_OK);
		return builder.build();
	}

	
	//====================== POST ======================//
	@POST
	@Produces(WSConstants.WS_PRODUCES)
	/**
	 * Create new list
	 * @return
	 */
	public Response postUser() {
		Response.ResponseBuilder builder = Response
				.status(Response.Status.CREATED);

		KeyGenerator generator = new KeyGenerator();

		User user = new User();
		user.setKey(generator.generateKey());

		UserDAO.getInstance().save(user);

		UserConverter userConverter = new UserConverter(user);

		builder.header(WSConstants.HEADER_LOCATION, context.getAbsolutePath());
		builder.entity(userConverter);

		LOG.debug(Users.LOG_OK);
		return builder.build();
	}

	
	//====================== DELETE ======================//
	@DELETE
	@Produces(WSConstants.WS_PRODUCES)
	/**
	 * Create new list
	 * @return
	 */
	public Response deleteUser(@Context HttpHeaders hh) {
		Response.ResponseBuilder builder = Response.status(Response.Status.OK);

		// try to find key in header
		key = AuthLibrary.getKey(hh, builder, LOG);
		if (key == null) {
			return builder.build();
		}

		// check key format
		if (AuthLibrary.checkKeyLength(key, builder, LOG) == false) {
			return builder.build();
		}

		try {
			User oldUser = UserDAO.getInstance().getByKey(key);

			if (oldUser == null) {
				builder.status(Response.Status.NOT_FOUND);
				builder.entity(new ErrorConverter(WSConstants.RESULT_NOT_FOUND));
				return builder.build();

			} else {
				UserDAO.getInstance().remove(oldUser.getId());

				builder.header(WSConstants.HEADER_LOCATION,
						context.getAbsolutePath());
				builder.entity(new InfoConverter(Users.DELETE_COMPLETE));
			}

		} catch (NullPointerException ex) {
			builder.status(Response.Status.BAD_REQUEST);
			builder.entity(new ErrorConverter(DBConstants.DB_BAD_DATA_FORMAT));
			LOG.error(WSConstants.RESULT_FAILED,
					ex);
			return builder.build();
		}

		LOG.debug(Users.LOG_OK);
		return builder.build();
	}

}
